using System.Runtime.CompilerServices;

namespace GameFrame
{
    public struct EntityRef
    {
        public const int SIZE = 8;
        internal long Raw;
        public int Index;
        public int Version;
        public int Id { get; set; }

        public static EntityRef None => new EntityRef();
        
        public static bool operator ==(EntityRef a, EntityRef b) => (long) a.Raw == (long) b.Raw;

        public static bool operator !=(EntityRef a, EntityRef b) => (long) a.Raw != (long) b.Raw;

        public bool Equals(EntityRef other) => (long) this.Raw == (long) other.Raw;

        public override bool Equals(object obj) => obj is EntityRef other && this.Equals(other);

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override int GetHashCode() => this.Version + this.Index * 59209;

        public static unsafe void Serialize(void* ptr, FrameSerializer stream)
        {
            EntityRef* entityRefPtr = (EntityRef*) ptr;
            if (stream.InputMode)
            {
                if (stream.Stream.Condition(entityRefPtr->Index != 0))
                {
                    stream.Stream.Serialize(&entityRefPtr->Index);
                    stream.Stream.Serialize(&entityRefPtr->Version);
                }
                else if (stream.Reading)
                {
                    entityRefPtr->Index = 0;
                    entityRefPtr->Version = 0;
                }
            }
            else
            {
                stream.Stream.Serialize(&entityRefPtr->Index);
                stream.Stream.Serialize(&entityRefPtr->Version);
            }
        }
    }
}